/*===========================================

	True Love Wii

	Coders:
		GizmoTheGreen
		TalkLittle

	Credits:
		NoNameNo

============================================*/

#include "common.h"

static void changeBgImage(const char *filename /* TODO other params from script: scaled size etc. */);

// XXX not sure if offset is needed
int readScript(const char *scriptFile, u16 offset) {
	FILE *fp;
	u16 topOffset;
	u8 currByte;
	char filenameBuf[12]; // max 7 + .ext + \0
	void *argList;

	// TODO keep files open, and keep a list of file pointers??
	fp = fopen(scriptFile, "rb");
	if (offset == 0) {
		// script files have a 16-bit big-endian offset as first 2 bytes
		fread(&topOffset, 1, 2, fp);
		if (endianness == 0) {
			// convert big endian to little endian
			bswap_16(&topOffset);
		}
		fseek(fp, topOffset, SEEK_SET);
	}

	for (;;) {
		// Read until you get a "return" opcode or EOF
		// XXX does a "return" code even exist???

		if (feof(fp)) {
			break;
		}
		fread(&currByte, 1, 1, fp);

		// TODO change below switch to a table of function pointers...
		switch(currByte) {

		//
		// IMAGE DISPLAY STUFF
		//
		case 51:  // 0x33
			fread(&currByte, 1, 1, fp); // currByte := 1 + length of filename
			fread(filenameBuf, 1, currByte-1, fp);
			strcat(filenameBuf, ".MRS");
			fread(&currByte, 1, 1, fp); // additional args?
			if (!currByte) {
				// No additional args
				// XXX use a stack here too? (see below)
				changeBgImage(filenameBuf);
				break;
			}

			fread(&currByte, 1, 1, fp); // len additional args
			switch(currByte) {
			case 54:  // 0x36
				fread(&currByte, 1, 1, fp); // currByte := len(add'l args)
				argList = malloc(currByte);
				fread(argList, currByte, 1, fp);
				// TODO overlay a struct on the argList... once we figure out the struct

				// TODO use a stack... I think that's how they do animations for intro
				changeBgImage(filenameBuf, argList, currByte); // file, args, len(args)
				break;

			default:
				// We weren't expecting this image opcode
				// TODO print an error
				break;
			}
			break;

		case 82:  // 0x52 (MAIN.DAT: TITLE.MRS)
			// Display image without using stack???
			fread(&currByte, 1, 1, fp); // currByte := 1 + length of filename
			fread(filenameBuf, 1, currByte-1, fp);
			strcat(filenameBuf, ".MRS");
			fread(&currByte, 1, 1, fp); // additional args?
			if (!currByte) {
				// No additional args
				// XXX use a stack here too? (see below)
				changeBgImage(filenameBuf);
				break;
			}
			// XXX does opcode 0x52 ever display image with args?
			break;

		case 65:  // 0x41 (MAIN.DAT: after TITLE.MRS)
			fread(&currByte, 1, 1, fp); // currByte := len(add'l args)
			argList = malloc(currByte);
			fread(argList, currByte, 1, fp);
			// TODO overlay a struct on the argList... once we figure out the struct

			break;
		//
		// END IMAGE DISPLAY STUFF
		//

		case 152: // 0x98 (MAIN.DAT: offset 0x101A after title images)
			// XXX I think involves actual game logic
			break;

		case 132: // 0x84 (MAIN.DAT: WIN.MRS)
		case 22:  // 0x16 (MAIN.DAT: WIN.MRS)
		case 135: // 0x87 (MAIN.DAT: CMK.MRS)
		case 157: // 0x9D (MAIN.DAT)
		case 133: // 0x85 (MAIN.DAT)
		case 115: // 0x73 (MAIN.DAT)
		case 114: // 0x72 (MAIN.DAT)
		case 43:  // 0x2B (MAIN.DAT)
			// An initializer, I think; skip since we don't need it
			fread(&currByte, 1, 1, fp); // length of args
			fseek(fp, currByte, SEEK_CUR); // skip it...
			break;

		default:
			// We weren't expecting this opcode
			// TODO print an error
			break;
		}
	}
	return 1;
}

/* TODO other params from script: scaled size etc. */
static void changeBgImage(const char *filename) {

	MRS_ChangeFile(filename, &MRS_bg_data, MRS_bg_colorTable,
		&MRS_bg_width, &MRS_bg_height);
}
